"""
算法得出的结论，永远不是100%确定的，更多的是判断出了一种“样本的标签更可能是某类的可能性”，而非一种“确定”。

每种算法使用不同的指标来衡量这种可能性。
决策树使用的就是叶子节点上占比较多的标签所占的比例（接口predict_proba调用）
逻辑回归使用的是sigmoid函数压缩后的似然（接口predict_proba调用）
SVM使用的是样本点到决策边界的距离（接口decision_function调用）
实都是一种“类概率”的表示

真正的概率算法：朴素贝叶斯
朴素贝叶斯是一种直接衡量标签和特征之间的概率关系的有监督算法，它既可以做回归也可以分类，不过多是用于分类之中。
朴素贝叶斯的算法根源就是基于概率论和数理统计的贝叶斯理论，因此它是根正苗红的概率模型。

在概率论中，我们可以证明，两个事件的联合概率等于这两个事件任意条件概率 * 这个条件事件本身的概率。

联合概率：P(X,Y)，两件事情同时发生的概率。
条件概率：P(X|Y)，在Y发生的前提下，X发生的概率。

P(X,Y)=P(X|Y)*P(Y)=P(Y|X)*P(X)
X,Y同时发生的概率 = Y发生前提下X发生的概率 * Y发生的概率 = X发生前提下Y发生的概率 * X发生的概率
贝叶斯公式：P(Y|X)=P(X|Y)*P(Y)/Y(X)
在X发生情况下Y发生的概率 = 在Y发生前提下X发生的概率 * Y发生的概率 / X发生的概率

后验概率（posterior probability），即是说我们先知道了条件，再去求解结果。
标签的先验概率（prior probability），是完全没有任何条件限制的，


在Y=1的条件下，X的多种取值被同时取到的概率，就等于Y=1的条件下，X的多种取值被分别取到的概率相乘。

假设特征之间是有条件独立的，可以解决众多问题，也简化了很多计算过程，这是朴素贝叶斯被称为”朴素“的理由。
因此，贝叶斯在特征之间有较多相关性的数据集上表现不佳，而现实中的数据多多少少都会有一些相关性，所以贝叶斯的分类效力在分类算法中不算特别强大。

朴素贝叶斯是一个不建模的算法。是第一个有监督的，不建模的分类算法。

由于贝叶斯是从概率角度进行估计，它所需要的样本量比较少。如果样本量少于特征数目，贝叶斯的效果就会被削弱。
因为本质是在每个特征上单独对概率进行计算，然后再求乘积，所以每个特征上的计算可以是独立并且并行的，因此贝叶斯的计算速度比较快。

最常用的几个分布分别是：高斯分布，伯努利分布和多项式分布
sklearn朴素贝叶斯的分类器
naive_bayes.BernoulliNB 伯努利分布下的朴素贝叶斯

naive_bayes.GaussianNB  高斯分布下的朴素贝叶斯
高斯朴素贝叶斯，通过假设条件概率是服从高斯分布（也就是正态分布），来估计每个特征下每个类别上的条件概率。
贝叶斯没有太多的参数可以调整
prior           表示类的先验概率。如果指定，则不根据数据调整先验，如果不指定，则自行根据数据计算先验概率 。
var_smoothing   在估计方差时，为了追求估计的稳定性，将所有特征的方差中最大的方差以某个比例添加到估计的方差中。这个比例，由var_smoothing参数控制。

naive_bayes.MultinomialNB 多项式分布下的朴素贝叶斯
naive_bayes.ComplementNB 补充朴素贝叶斯
linear_model.BayesianRidge 贝叶斯岭回归，在参数估计过程中使用贝叶斯回归技术来包括正则化参数

"""
import numpy as np
import matplotlib.pyplot as plt
from sklearn.naive_bayes import GaussianNB
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
digits = load_digits()
X, y = digits.data, digits.target
Xtrain,Xtest,Ytrain,Ytest = train_test_split(X,y,test_size=0.3,random_state=420)

gnb = GaussianNB().fit(Xtrain,Ytrain)
#查看分数
acc_score = gnb.score(Xtest,Ytest)
print(acc_score)
#查看预测结果
Y_pred = gnb.predict(Xtest)
print(Y_pred)
#查看预测的概率结果
prob = gnb.predict_proba(Xtest)
print(prob.shape)

# 使用混淆矩阵来查看贝叶斯的分类结果
from sklearn.metrics import confusion_matrix as CM
print(CM(Ytest,Y_pred))

"""
概率预测的准确程度被称为“校准程度”，是衡量算法预测出的概率和真实概率的差异的一种方式。在二分类中，最常用的指标叫做布里尔分数，它被计算为是概率预测相对于测试样本的均方误差。
"""

# from sklearn.metrics import brier_score_loss
# print(brier_score_loss(Ytest, prob[:,0], pos_label=0))
# # pos_label与prob中的索引一致，就可以查看这个类别下的布里尔分数是多少
